#include <stdio.h>


//#pragma pack(1)

// 类型本身是不占用空间的
// 类型产生的变量才占空间
// 结构体中的每个成员的地址均是可以获得的。

//  1.为什么 sex 后面空了 3 字节，然后再去填 age
// 2. 为什么 age 后面的 num 后面空了 2 字节
// 3. sex 于 age 之间空了 3 字节，num 应该填在那个位置

// 用多个机器周期去读一个变量，这种现象造成的原因是内存不对齐
// 要实现内存对齐，牺牲空间换取时间。

#if 0
// x86 linux 默认 #pragma pack(4)
// Linux 最大支持 4 字节对齐
// window 默认 #pragma pack(8)

// 1. 取 pack(n) 的值 (n = 1, 2, 4, 8...) 取结构体中的最大值 m。
// 两者取小即为 外对齐，大小 Y = (m<n?m:n)
// 2. 将每一个结构体的成员大小于 Y 比较取小者为 X ，作为 内对齐 大小
// 3. 所谓按 X 对齐，即为地址（设起始地址为 0）能被 X 整除，的地址开始存取数据。
// 4. 外部对齐原则是依据 Y 的值（ Y 的最小整数倍）进行补空操作。

pack n  8      4   m
外对齐原则       Y = 4
        char   1
        short  2
        int    4
               X = 1
                 = 2
                 = 4
内对齐原则       X = 2


pack n  8      4   m
外对齐原则       Y = 4
        char   1
        int    4
        short  2
               X = 1
                 = 4
                 = 2
内对齐原则       X = 4

#pragma pack(1)
pack n  1      4   m
外对齐原则       Y = 1
        char   1
        int    4
        short  2
               X = 1
                 = 4
                 = 2
内对齐原则       X = 1

#endif

typedef struct _staff
{
//    char sex;
//    int age;
//    short num;
    char sex;
    short num;
    int age;
}Staff;
int main()
{
    Staff s;

    printf("sizeof(Staff) = %d\n",sizeof (Staff));
    printf("sizeof(s)     = %d\n",sizeof (s));

    printf("&s = %p\n", &s);
//    printf("&s.sex = %p\n", &s.sex);
//    printf("&s.age = %p\n", &s.age);
//    printf("&s.num = %p\n", &s.num);
    printf("&s.sex = %p\n", &s.sex);
    printf("&s.num = %p\n", &s.num);
    printf("&s.age = %p\n", &s.age);
    return 0;
}
